On this page

Skip to content

Implementing GDPR in ASP.NET Core

General Data Protection Regulation

When browsing the web, if you see a message like "This site uses cookies, do you accept?", this originates from the "General Data Protection Regulation (GDPR)," a regulation passed by the European Union on April 27, 2016, and enforced starting May 25, 2018. Its purpose is to regulate the data and privacy of individuals within the EU. For the full content, please refer to Wiki GDPR.

In addition to the EU's GDPR, the US state of California has similar regulations, such as the California Consumer Privacy Act (CCPA) and the California Online Privacy Protection Act (CalOPPA).

Implementation Methods

  • Create a Privacy Policy page: If you use Visual Studio to create a .NET Core 2.1 or later Web project, you will notice an additional "Privacy" page. This is used to display the website's Privacy Policy. For a sample privacy policy, you can refer to Chinese Privacy Policy Template for Websites. According to the author, this is an adjusted version based on the "Government Website Layout and Content Management Guidelines." However, I could not find the original template. If it is for commercial use, it is best to verify whether the content complies with regulations like GDPR.

  • Displaying cookie usage information on the webpage:

    • Provide a link to the "Privacy and Cookie Policy" page.
    • Ask for consent to the policy. Approaches generally fall into the following categories:
      • No prompt, just a notification that continuing to use the site implies consent to the privacy policy, with a "Close" button.
      • Notification that continuing to use the site implies consent, with "Accept" and "Close" buttons.
      • Not assuming consent by default, providing "Accept" and "Close" buttons.
      • Categorizing cookies used on the site, allowing users to consent only to necessary cookies. "Stack Overflow" is an example of this. If you are interested, you can browse in Incognito mode to see that they provide a "Customize settings" button, allowing you to adjust the types of cookies you allow.
    • Handling the closing of the notification message:
      • Close: Only hides it temporarily from the screen; the message will reappear when the page is reloaded.
      • Accept: Writes a flag to a cookie. When this cookie exists, the notification message is no longer displayed, and subsequent actions may depend on this flag to decide whether to write other cookies.
  • Methods for not writing cookies until the user consents: Some sites inform users that "continuing to use this site implies consent to the privacy policy" because they do not want to handle the logic of stopping cookie writes. Therefore, they assume user consent by default and explain in the privacy policy that users can adjust browser settings to block cookies. Of course, reasonably speaking, non-essential cookies should be blocked until the user provides consent.

    Implementing this part is not difficult. Instead of using the native framework API, you can write a Facade to encapsulate it. Only call the native API when the user's consent cookie is present.

    In MVC, the simplest approach is to write a BasicController that other controllers inherit from, using its AddCookie method to add a Response cookie. Example:

csharp
public abstract BasicController {
    public void AddCookie(HttpCookie cookie) {
        // Adjust Cookie Name and Value according to actual requirements
        if (Request.Cookies["UseCookies"] == "yes") {
            Response.Cookies.Add(cookie);
        }
    }
}

Implementation in ASP.NET Core

The .NET Core 2.1 project template already included a GDPR implementation (excluding the privacy policy content). However, in later versions (I haven't tested which specific version, but MSDN states templates are provided from 2.2 onwards), the page implementation was removed, leaving only the API. Nevertheless, MSDN provides a GDPR implementation sample. Basically, besides adjusting the HTML to match your UI kit and modifying the text according to your policy, this sample is what I will explain here (if you don't use jQuery, you'll need to adjust it; for some reason, the code uses native DOM APIs but still relies on $.ready()).

Below, I use "Consent" to represent the cookie for "Allow Cookie Usage Settings."

Program.cs

csharp
builder.Services.Configure<CookiePolicyOptions>(options => {
    // If set to true, "Consent" is required to set non-essential cookies
    options.CheckConsentNeeded = context => true;

    options.MinimumSameSitePolicy = SameSiteMode.None;
});

// ...other code...

app.UseCookiePolicy(); // Cookie-related Middleware is configured here

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

_CookieConsentPartial.cshtml

  • The default Injection Instance type for ITrackingConsentFeature is ResponseCookiesWrapper (the specific DI behavior occurs in app.UseCookiePolicy()).
  • The value of consentFeature?.CanTrack is CookiePolicyOptions.CheckConsentNeeded(HttpContext) == true AND the presence of the "Consent" cookie. In other words, if CheckConsentNeeded = context => false is set in Program.cs, the reminder will not be displayed.
  • consentFeature?.CreateConsentCookie() is used to create the "Consent" string, which looks roughly like .AspNet.Consent=yes; expires={date}; path=/; secure. The "Consent" cookie is not actually created here, but rather when document.cookie = button.dataset.cookieString; is executed.
html
@using Microsoft.AspNetCore.Http.Features

@{
    var consentFeature = Context.Features.Get<ITrackingConsentFeature>();
    var showBanner = !consentFeature?.CanTrack ?? false;
    var cookieString = consentFeature?.CreateConsentCookie();
}

@if (showBanner) {
    <div id="cookieConsent" class="alert alert-info alert-dismissible fade show" role="alert">
        Use this space to summarize your privacy and cookie use policy. <a asp-page="/Privacy">Learn More</a>.
        <button type="button" class="accept-policy close" data-dismiss="alert" aria-label="Close" data-cookie-string="@cookieString">
            <span aria-hidden="true">Accept</span>
        </button>
    </div>
    <script>
        (function () {
            var button = document.querySelector("#cookieConsent button[data-cookie-string]");
            button.addEventListener("click", function (event) {
                document.cookie = button.dataset.cookieString;
            }, false);
        })();
    </script>
}

Essential Cookies

Some cookies are non-essential, such as those used for preferences to optimize user experience. However, some cookies affect the normal operation of the website. If you want the site to function normally even if the user has not consented to cookie usage (the notification message should ideally explain this situation), such cookies should be set with IsEssential = true.

csharp
Response.Cookies.Append("name", "value", new CookieOptions {
   IsEssential = true // Indicates that this cookie is essential
});

Change Log

  • 2022-10-27 Initial document created.